package cn.wolfcode.shop.web.controller;

import cn.wolfcode.shop.domain.SeckillOrder;
import cn.wolfcode.shop.domain.User;
import cn.wolfcode.shop.mq.MQSender;
import cn.wolfcode.shop.mq.OrderMessage;
import cn.wolfcode.shop.redis.RedisService;
import cn.wolfcode.shop.redis.SeckillGoodPrefixKey;
import cn.wolfcode.shop.redis.SeckillOrderPrefixKey;
import cn.wolfcode.shop.result.CodeMsg;
import cn.wolfcode.shop.result.Result;
import cn.wolfcode.shop.service.ISeckillGoodService;
import cn.wolfcode.shop.service.ISeckillService;
import cn.wolfcode.shop.util.MD5Util;
import cn.wolfcode.shop.vo.GoodVo;
import cn.wolfcode.shop.web.util.AccessLimit;
import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.jms.JMSException;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by wolfcode-lanxw
 */
@Controller
@RequestMapping("/seckill")
public class SecKillController {
    public static ConcurrentHashMap<Long,Boolean> localOverMap = new ConcurrentHashMap<Long,Boolean>();
    @Reference
    private ISeckillGoodService seckillGoodService;
    @Reference
    private ISeckillService seckillService;
    @Autowired
    private MQSender msgSender;
    @Autowired
    private RedisService redisService;
    @RequestMapping("/{path}/do_seckill")
    @ResponseBody
    public Result<Integer> seckill(Long goodId, @PathVariable("path") String path, User user,String uuid){
        if(user==null){
            return Result.error(CodeMsg.LOGIN_INVAILD);
        }
        Boolean isOver = localOverMap.get(goodId);
        if(isOver!=null && isOver){
            return Result.error(CodeMsg.STOCK_OVER);
        }
        String oldPath = redisService.get(SeckillGoodPrefixKey.SECKILL_PATH, user.getId() + ":" + goodId, String.class);
        if(!oldPath.equals(path)){
            return Result.error(CodeMsg.ILLEGAL_OP);
        }
        GoodVo goodVo = seckillGoodService.getById(goodId);
        if(goodVo.getStartDate().getTime()-new Date().getTime()>0){
            return Result.error(CodeMsg.ILLEGAL_OP);
        }

        SeckillOrder seckillOrder = redisService.get(SeckillOrderPrefixKey.SECKILL_ORDER, user.getId() + ":" + goodId, SeckillOrder.class);
        if(seckillOrder!=null){
            return Result.error(CodeMsg.SECKILL_REPEAT);
        }
        Long stock = redisService.decr(SeckillGoodPrefixKey.SECKILL_STOCK, goodId + "");
        if(stock<0){
            localOverMap.put(goodId,true);
            return Result.error(CodeMsg.STOCK_OVER);
        }
        OrderMessage orderMessage = new OrderMessage();
        orderMessage.setUserId(user.getId());
        orderMessage.setGoodId(goodId);
        orderMessage.setUuid(uuid);
        try {
            msgSender.sendOrderMsg(orderMessage);
        } catch (JMSException e) {
            //TODO
            seckillService.syncStock(goodId);
            return Result.error(CodeMsg.SECKILL_ERROR);
        }
        return Result.success(0);
    }
    @AccessLimit(seconds = 5,maxCount = 5,needLogin = true)
    @RequestMapping("/getPath")
    @ResponseBody
    public Result getPath(Long goodId,Integer verifyCode, User user){
        if(user==null){
            return Result.error(CodeMsg.LOGIN_INVAILD);
        }
        if(StringUtils.isEmpty(verifyCode)){
            return Result.error(CodeMsg.VERIFYCODE_ERROR);
        }
        Integer result = redisService.get(SeckillGoodPrefixKey.SECKILL_VERIFYCODE_RESULT,user.getId()+":"+goodId,int.class);
        if(result==null || result - verifyCode!=0){
            return Result.error(CodeMsg.VERIFYCODE_ERROR);
        }
        String path = MD5Util.md5(UUID.randomUUID().toString());
        redisService.set(SeckillGoodPrefixKey.SECKILL_PATH,user.getId()+":"+goodId,path);
        return Result.success(path);
    }
}
